#pragma once

#include "Memory.h"
#include "Singleton.h"
#include "Logging.h"
#include "InputMgr.h"
#include "ResourceMgr.h"


struct GLFWwindow;
typedef struct FT_LibraryRec_  *FT_Library;
typedef struct FT_FaceRec_*  FT_Face;

namespace a2d
{
//------------------------------------------------------------------
	
	class Render;
	class RenderState;
	class InputListener;

	struct AV2D_EXPORT EngineDesc
	{
		ushort Width = 640;
		ushort Height = 480;
		char *Title = "Asura2D Engine";
		bool Resize = true;
		bool Vsync = false;
	};

	class AV2D_EXPORT Engine : public Singleton<Engine>
	{
		//DumpMemoryLeak;
	public:
		Engine();
		~Engine();
		bool Init(const EngineDesc &desc);
		
		bool BeginFrame();
		void EndFrame();		

		void Destroy();

		ushort GetWidth() { return m_desc.Width; }
		ushort GetHeight() { return m_desc.Height; }

		void AddInputListener(InputListener *Listener);

		void SetClearColor(uchar r, uchar g, uchar b);

	private:
		friend static void resize_callback(GLFWwindow*, int, int);
		friend static void mouse_button_callback(GLFWwindow*, int, int, int);
		friend static void cursor_position_callback(GLFWwindow*, double, double);
		friend static void scroll_callback(GLFWwindow*, double, double);
		friend static void key_callback(GLFWwindow*, int, int, int, int);
		friend static void char_callback(GLFWwindow*, unsigned int);
		friend static void char_mods_callback(GLFWwindow*, unsigned int, int);
		
		void resize(ushort w, ushort h);

		Log m_log;

		EngineDesc m_desc;

		GLFWwindow *m_window;
		Render *m_render;
		RenderState *m_renderstate;
		InputMgr m_input;

		FT_Library m_ft;
		FT_Face m_face;

		double m_starttime;

		ResourceMgr m_resourcemgr;
	};

//------------------------------------------------------------------
} // namespace a2d
